1 /* 2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /********************************************************************** 27 ********************************************************************** 28 ********************************************************************** 29 *** COPYRIGHT (c) Eastman Kodak Company, 1997 *** 30 *** As an unpublished work pursuant to Title 17 of the United *** 31 *** States Code. All rights reserved. *** 32 ********************************************************************** 33 ********************************************************************** 34 **********************************************************************/ 35 36 package java.awt.color; 37 38 import java.awt.image.LookupTable; 39 import sun.java2d.cmm.ProfileDeferralInfo; 40 41 /** 42 * 43 * The ICC_ProfileRGB class is a subclass of the ICC_Profile class 44 * that represents profiles which meet the following criteria: 45 * <ul> 46 * <li>The profile's color space type is RGB.</li> 47 * <li>The profile includes the <code>redColorantTag</code>, 48 * <code>greenColorantTag</code>, <code>blueColorantTag</code>, 49 * <code>redTRCTag</code>, <code>greenTRCTag</code>, 50 * <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li> 51 * </ul> 52 * The <code>ICC_Profile</code> <code>getInstance</code> method will 53 * return an <code>ICC_ProfileRGB</code> object when these conditions are met. 54 * Three-component, matrix-based input profiles and RGB display profiles are 55 * examples of this type of profile. 56 * <p> 57 * This profile class provides color transform matrices and lookup tables 58 * that Java or native methods can use directly to 59 * optimize color conversion in some cases. 60 * <p> 61 * To transform from a device profile color space to the CIEXYZ Profile 62 * Connection Space, each device color component is first linearized by 63 * a lookup through the corresponding tone reproduction curve (TRC). 64 * The resulting linear RGB components are converted to the CIEXYZ PCS 65 * using a a 3x3 matrix constructed from the RGB colorants. 66 * <pre> 67 * 68 * linearR = redTRC[deviceR] 69 * 70 * linearG = greenTRC[deviceG] 71 * 72 * linearB = blueTRC[deviceB] 73 * 74 * _ _ _ _ _ _ 75 * [ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ] 76 * [ ] [ ] [ ] 77 * [ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ] 78 * [ ] [ ] [ ] 79 * [_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _] 80 * 81 * </pre> 82 * The inverse transform is performed by converting PCS XYZ components to linear 83 * RGB components through the inverse of the above 3x3 matrix, and then converting 84 * linear RGB to device RGB through inverses of the TRCs. 85 * <p> 86 */ 87 88 89 90 public class ICC_ProfileRGB 91 extends ICC_Profile { 92 93 static final long serialVersionUID = 8505067385152579334L; 94 95 /** 96 * Used to get a gamma value or TRC for the red component. 97 */ 98 public static final int REDCOMPONENT = 0; 99 100 /** 101 * Used to get a gamma value or TRC for the green component. 102 */ 103 public static final int GREENCOMPONENT = 1; 104 105 /** 106 * Used to get a gamma value or TRC for the blue component. 107 */ 108 public static final int BLUECOMPONENT = 2; 109 110 111 /** 112 * Constructs an new <code>ICC_ProfileRGB</code> from a CMM ID. 113 * 114 * @param ID The CMM ID for the profile. 115 * 116 */ 117 ICC_ProfileRGB(long ID) { 118 super(ID); 119 } 120 121 /** 122 * Constructs a new <code>ICC_ProfileRGB</code> from a 123 * ProfileDeferralInfo object. 124 * 125 * @param pdi 126 */ 127 ICC_ProfileRGB(ProfileDeferralInfo pdi) { 128 super(pdi); 129 } 130 131 132 /** 133 * Returns an array that contains the components of the profile's 134 * <CODE>mediaWhitePointTag</CODE>. 135 * 136 * @return A 3-element <CODE>float</CODE> array containing the x, y, 137 * and z components of the profile's <CODE>mediaWhitePointTag</CODE>. 138 */ 139 public float[] getMediaWhitePoint() { 140 return super.getMediaWhitePoint(); 141 } 142 143 144 /** 145 * Returns a 3x3 <CODE>float</CODE> matrix constructed from the 146 * X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>, 147 * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>. 148 * <p> 149 * This matrix can be used for color transforms in the forward 150 * direction of the profile--from the profile color space 151 * to the CIEXYZ PCS. 152 * 153 * @return A 3x3 <CODE>float</CODE> array that contains the x, y, and z 154 * components of the profile's <CODE>redColorantTag</CODE>, 155 * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>. 156 */ 157 public float[][] getMatrix() { 158 float[][] theMatrix = new float[3][3]; 159 float[] tmpMatrix; 160 161 tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag); 162 theMatrix[0][0] = tmpMatrix[0]; 163 theMatrix[1][0] = tmpMatrix[1]; 164 theMatrix[2][0] = tmpMatrix[2]; 165 tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag); 166 theMatrix[0][1] = tmpMatrix[0]; 167 theMatrix[1][1] = tmpMatrix[1]; 168 theMatrix[2][1] = tmpMatrix[2]; 169 tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag); 170 theMatrix[0][2] = tmpMatrix[0]; 171 theMatrix[1][2] = tmpMatrix[1]; 172 theMatrix[2][2] = tmpMatrix[2]; 173 return theMatrix; 174 } 175 176 /** 177 * Returns a gamma value representing the tone reproduction curve 178 * (TRC) for a particular component. The component parameter 179 * must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT. 180 * <p> 181 * If the profile 182 * represents the TRC for the corresponding component 183 * as a table rather than a single gamma value, an 184 * exception is thrown. In this case the actual table 185 * can be obtained through the {@link #getTRC(int)} method. 186 * When using a gamma value, 187 * the linear component (R, G, or B) is computed as follows: 188 * <pre> 189 * 190 * gamma 191 * linearComponent = deviceComponent 192 * 193 *</pre> 194 * @param component The <CODE>ICC_ProfileRGB</CODE> constant that 195 * represents the component whose TRC you want to retrieve 196 * @return the gamma value as a float. 197 * @exception ProfileDataException if the profile does not specify 198 * the corresponding TRC as a single gamma value. 199 */ 200 public float getGamma(int component) { 201 float theGamma; 202 int theSignature; 203 204 switch (component) { 205 case REDCOMPONENT: 206 theSignature = ICC_Profile.icSigRedTRCTag; 207 break; 208 209 case GREENCOMPONENT: 210 theSignature = ICC_Profile.icSigGreenTRCTag; 211 break; 212 213 case BLUECOMPONENT: 214 theSignature = ICC_Profile.icSigBlueTRCTag; 215 break; 216 217 default: 218 throw new IllegalArgumentException("Must be Red, Green, or Blue"); 219 } 220 221 theGamma = super.getGamma(theSignature); 222 223 return theGamma; 224 } 225 226 /** 227 * Returns the TRC for a particular component as an array. 228 * Component must be <code>REDCOMPONENT</code>, 229 * <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>. 230 * Otherwise the returned array 231 * represents a lookup table where the input component value 232 * is conceptually in the range [0.0, 1.0]. Value 0.0 maps 233 * to array index 0 and value 1.0 maps to array index length-1. 234 * Interpolation might be used to generate output values for 235 * input values that do not map exactly to an index in the 236 * array. Output values also map linearly to the range [0.0, 1.0]. 237 * Value 0.0 is represented by an array value of 0x0000 and 238 * value 1.0 by 0xFFFF. In other words, the values are really unsigned 239 * <code>short</code> values even though they are returned in a 240 * <code>short</code> array. 241 * 242 * If the profile has specified the corresponding TRC 243 * as linear (gamma = 1.0) or as a simple gamma value, this method 244 * throws an exception. In this case, the {@link #getGamma(int)} 245 * method should be used to get the gamma value. 246 * 247 * @param component The <CODE>ICC_ProfileRGB</CODE> constant that 248 * represents the component whose TRC you want to retrieve: 249 * <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or 250 * <CODE>BLUECOMPONENT</CODE>. 251 * 252 * @return a short array representing the TRC. 253 * @exception ProfileDataException if the profile does not specify 254 * the corresponding TRC as a table. 255 */ 256 public short[] getTRC(int component) { 257 short[] theTRC; 258 int theSignature; 259 260 switch (component) { 261 case REDCOMPONENT: 262 theSignature = ICC_Profile.icSigRedTRCTag; 263 break; 264 265 case GREENCOMPONENT: 266 theSignature = ICC_Profile.icSigGreenTRCTag; 267 break; 268 269 case BLUECOMPONENT: 270 theSignature = ICC_Profile.icSigBlueTRCTag; 271 break; 272 273 default: 274 throw new IllegalArgumentException("Must be Red, Green, or Blue"); 275 } 276 277 theTRC = super.getTRC(theSignature); 278 279 return theTRC; 280 } 281 282 }